// Copyright (c) 2009 Luca Marrocco.
// Modified or written by Luca Marrocco for inclusion with codej.
// Licensed under the Apache License, Version 2.0 (the "License")
package codej.parser;

import static codej.parser.PathStrategies.*;

import java.io.*;

import codej.parser.java.*;

/** @author Luca Marrocco */
public class ParserAgent {
	
	private String baseDir = "src/test/java";
	private Class parserClass;

	public static ParserAgent using(Class parserClass) {
		return new ParserAgent(parserClass);
	}

	public ParserAgent(Class parserClass) {
		this.parserClass = parserClass;
	}

	public ParserAgent baseDir(String baseDir) {
		this.baseDir = baseDir;
		return this;
	}

	private Parser newParser(Class parserClass, String source) {
		try {
			return (Parser) parserClass.getConstructor(String.class).newInstance(source);
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
	}

	public final String pathTo(Object object) {
		return pathStrategyFor(object).pathTo(object);
	}

	public String read(Object object) {
		return slurp(userDir(baseDir), pathTo(object));
	}

	public String slurp(File file) {
		try {
			return slurp(new FileInputStream(file));
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
	}

	public String slurp(File directory, String path) {
		try {
			return slurp(new FileInputStream(new File(directory, path)));
		} catch (Exception e) {
			return slurp(new File(path));
		}
	}

	public String slurp(InputStream in) {
		try {
			StringBuffer out = new StringBuffer();
			byte[] b = new byte[4096];
			for (int n; (n = in.read(b)) != -1;) {
				out.append(new String(b, 0, n));
			}
			return out.toString();
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
	}

	public String tryParsing(Object object) {
		String source = read(object);
		Parser parser = newParser(parserClass, source);

		final StringBuffer stringBuffer = new StringBuffer();
		parser.attach(new TokenListener() {
			public void emit(String token) {
				stringBuffer.append(token).append(" ");
			}
		});
		parser.CompilationUnit();
		return stringBuffer.toString().trim();
	}

	public final File userDir(String path) {
		return new File(System.getProperty("user.dir"), path);
	}
}